{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Jupyter Widgets Tutorial Introduction\n",
    "# （Jupyter Widgets 教程简介）\n",
    "\n",
    "## How to ask questions\n",
    "## （如何提问）\n",
    "\n",
    "There is a \"raise hand\" button but instead, please use the chat or the Q/A. Prefer the chat, we will be able to answer your questions and interact in real-time through the chat. If need be we can have the host stop presenting to answer a question that's especially interesting or pertinent. We're not able to answer the Q/A questions unless we stop the flow of the tutorial to answer the question.\n",
    "（有一个“举手”按钮，但请使用聊天或问答。更喜欢聊天，我们将能够回答您的问题并通过聊天实时互动。如果需要，我们可以让主持人停止演示，回答特别有趣或相关的问题。除非我们停止教程的流程来回答问题，否则我们无法回答 Q/A 问题。）\n",
    "\n",
    "## Jupyter lab essentials\n",
    "## （Jupyter 实验室基础知识）\n",
    "\n",
    "+ To open a notebook: double-click it in the file browser.\n",
       "（要打开notebook：在文件浏览器中双击它。）\n",
    "+ To hide the file browser: click on the folder icon.\n",
    "（要隐藏文件浏览器：单击文件夹图标。）\n",
    "+ To run a single code cell in the notebook: Push `Shift` and `Enter`, or use the \"play\" button.\n",
    "（要在notebook中运行单个代码单元：按 Shift 和 Enter，或使用“播放”按钮。）\n",
    "+ To add a new view for an output, right-click on an output and select \"Create new view for output\".\n",
    "（要为输出添加新视图，请右键单击输出并选择“Create new view for output”（为输出创建新视图）。）\n",
    "+ Use tab to autocomplete and shift-tab to show documentation.\n",
    "（使用 tab 自动完成，使用 shift-tab 显示文档。）\n",
    "+ Use CTRL + \"/\" to comment/uncomment code",
    "（使用 Ctrl + “/” 注释/取消注释代码）\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Interactive Jupyter widgets\n",
    "## (交互式 Jupyter 小组件)\n",
    "\n",
    "A Python widget is an object that represents a control on the front end, like a slider. A single control can be displayed multiple times - they all represent the same python object.\n",
    "(Python 小组件是表示前端控件的对象，类似于滑块。单个控件可以多次显示 - 它们都表示同一个 python 对象。)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import ipywidgets as widgets"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "slider = widgets.FloatSlider(\n",
    "    value=7.5,\n",
    "    min=5.0,\n",
    "    max=10.0,\n",
    "    step=0.1,\n",
    "    description='Input:',\n",
    ")\n",
    "\n",
    "slider"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "You can trigger actions in the kernel when a control value changes by \"observing\" the value. Here we set a global variable when the slider value changes.\n",
    "（当控制值发生变化时，您可以通过 “观察” 该值来触发内核中的操作。在这里，当滑块值发生变化时，我们设置一个全局变量。）"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "square = slider.value * slider.value\n",
    "\n",
    "def handle_change(change):\n",
    "    global square\n",
    "    square = change.new * change.new\n",
    "    \n",
    "slider.observe(handle_change, 'value')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "square"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## `interact`: a shortcut for examining functions\n",
    "## （interact：检查函数的快捷方式）\n",
    "\n",
    "The `interact` function generates widgets based on a function's arguments and displays any output from the function.\n",
    "（interact 函数根据函数的参数生成小组件，并显示该函数的任何输出。）"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def f(x):\n",
    "    print(x * x)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "f(9)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import ipywidgets as ipw"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "widgets.interact(f, x=(0, 100));"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## How to load exercise solutions \n",
    "## （如何加载锻炼解决方案） \n",
    "\n",
    "Some exercises have solutions you can load if you prefer. To do that, uncomment the line with `%load` in it, then run the cell **twice**. The first time loads the solution, the second time runs the solution.\n",
    "（如果您愿意，可以加载一些练习的解决方案。为此，请取消注释其中包含 %load 的行，然后运行该单元格两次。第一次加载解决方案，第二次运行解决方案。）\n",
    "\n",
    "Here is a short exercise to try that with:\n",
    "（下面是一个简短的练习，可以尝试一下：）\n",
    "\n",
    "**In the cell below, use interact to generate a slider that goes from -10 to 10**\n",
    "**（在下面的单元格中，使用 interact 生成一个从 -10 到 10 的滑块）**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# %load solutions/intro/intro-example.py"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Additional reading\n",
    "## （补充阅读）\n",
    "\n",
    "### Behind the scenes\n",
    "### （幕后故事）\n",
    "\n",
    "Behind the scenes, even pure Python widgets are composed of two pieces:\n",
    "（在幕后，即使是纯 Python 小部件也由两部分组成：）\n",
    "\n",
    "+ Python, which runs in the notebook kernel.\n",
    "+（Python，在 notebook 内核中运行。）\n",
    "+ JavaScript, which runs in the browser.\n",
    "+（JavaScript，它在浏览器中运行。）\n",
    "\n",
    "When writing your own widgets, that means making a choice: write only in Python or write in both Python and Javascript.\n",
    "（在编写自己的小部件时，这意味着要做出选择：只用 Python 编写或同时使用 Python 和 Javascript 编写。）\n",
    "\n",
    "Which to choose depends on what you are trying to accomplish. This tutorial will focus on writing your own widgets in pure Python. An example of a pure-Python package that includes some interesting interfaces is [reducer](http://reducer.readthedocs.io), a package for calibrating astronomical data.\n",
    "（选择哪个取决于您要完成的任务。本教程将重点介绍如何用纯 Python 编写你自己的小部件。包含一些有趣接口的纯 Python 包的一个示例是 reducer，这是一个用于校准天文数据的包。）\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Jupyter widgets as a framework\n",
    "### （Jupyter 小部件作为框架）\n",
    "\n",
    "Jupyter widgets forms a framework for representing python objects interactively. Some large open-source interactive controls based on Jupyter widgets include:\n",
    "（Jupyter 小部件构成了一个以交互方式表示 python 对象的框架。一些基于 Jupyter 小组件的大型开源交互式控件包括：）\n",
    "\n",
    " - [bqplot](https://github.com/bqplot/bqplot/blob/master/examples/Index.ipynb) - 2d plotting library in which everything displayed is a widget\n",
    "（bqplot - 2D 绘图库，其中显示的所有内容都是小部件）\n",
    " - [ipympl](https://github.com/matplotlib/ipympl) - widget backend for [matplotlib](https://matplotlib.org/3.2.2/contents.html) graphics\n",
    "（IPYMPL - matplotlib 图形的小部件后端）\n",
    " - [pythreejs](https://pythreejs.readthedocs.io/en/stable/index.html) - low-level 3d graphics library\n",
    "（PyThreeJS - 低级 3D 图形库）\n",
    " - [ipyvolume](https://ipyvolume.readthedocs.io/en/latest/) - 3d plotting and volume rendering\n",
    "（ipyvolume - 3D 绘图和体积渲染）\n",
    " - [ipyleaflet](https://ipyleaflet.readthedocs.io/en/latest/)_ - interactive maps\n",
    "（ipyleaflet_ - 交互式地图）\n",
    " - [ipywebrtc](https://github.com/maartenbreddels/ipywebrtc) - video streaming\n",
    "（IPYWebRTC - 视频流）\n",
    " - [ipysheet](https://ipysheet.readthedocs.io/en/latest/) - interactive spreadsheets\n",
    "（IPYSHEET - 交互式电子表格）\n",
    " - [ipytree](https://github.com/QuantStack/ipytree) - tree for viewing hierarchical material\n",
    "（ipytree - 用于查看分层材料的树）\n",
    " - [ipycanvas](https://ipycanvas.readthedocs.io/en/latest/?badge=latest) - interactive drawing in a notebook\n",
    "（ipycanvas - 笔记本中的交互式绘图）\n",
    " - [ipyevents](https://github.com/mwcraig/ipyevents/blob/master/doc/Widget%20DOM%20Events.ipynb) - capture mouse/keyboard events on a widget\n",
    "（ipyevents - 捕获 Widget 上的鼠标/键盘事件）\n",
    " - ..."
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "widgets-tutorial",
   "language": "python",
   "name": "widgets-tutorial"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.10"
  },
  "widgets": {
   "state": {
    "0cb2d81d826b4e25aba3b1d39711ef3f": {
     "views": [
      {
       "cell_index": 6
      }
     ]
    },
    "2cfe6521f9834ca69e54518716104cd2": {
     "views": [
      {
       "cell_index": 8
      },
      {
       "cell_index": 9
      },
      {
       "cell_index": 12
      }
     ]
    },
    "889356d59ac543a49da33d134d791c3f": {
     "views": [
      {
       "cell_index": 11
      }
     ]
    }
   },
   "version": "2.0.0-dev"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
